import { Injectable } from '@angular/core'
import { Validators, FormGroup } from '@angular/forms'
import { FieldBase } from './field-base.interface'
import { HiddenField } from './field-hidden.interface'
import { NumberField } from './field-number.interface'
import { MCCSelectField } from './field-mcc.interface'
import { MCCType, IMCC } from '@shared/components/mcc-select/mcc-select.interface'
import { GroupField } from './field-group.interface'
import { QrChannel, UPIChannel } from '@shared/interfaces/acquirer'
import {
  alphanumericReg,
  AlipaySecondaryMerIDMaxLength,
  AlipaySecondaryMerNameMaxLength,
  AlipayStoreIDMaxLength,
  AlipayStoreNameMaxLength,
  WeChatSubMerIDMaxLength,
  TruMerIDMaxLength,
  TruMerIDMinLength,
  onlyNumberReg,
} from 'app/utils/contraints'
import { IQRRouteOfStore, IStoreChanMerAlipay, IStoreChanMerWeChat, IStoreChanMerUPI, IStoreChanMerTRU } from '@shared/interfaces/store'
import { ChanMerSelectField } from './field-chan-mer-select.interface'
import { TextboxField } from './field-textbox.interface'
import { SelectField } from './field-select.interface'
import { I18NService } from '@core'
import { CheckboxField } from './field-checkbox.interface'
import { DataService } from '@shared/services/data.service'

@Injectable()
export class ChannelFormQRService {
  constructor(private i18n: I18NService,
              private dataService: DataService,
    ) {}

  getAlipayChannelFields(val?: IQRRouteOfStore): FieldBase<any>[] {
    let selectedChanMer = null
    let cmp: IStoreChanMerAlipay
    if (val && val.chanMerParams) {
      cmp = val.chanMerParams as IStoreChanMerAlipay
      if (cmp.PID) {
        selectedChanMer = new QrChannel()
        selectedChanMer.id = val.chanMerObjId
        selectedChanMer.chanMerID = cmp.PID
      }
    }

    if (val.mccNameEN && (val.mcc as IMCC)) {
      val.mcc = {
        mccEnName: val.mccNameEN,
        mccCode: val.mcc as string,
      }
    }
    const fields: FieldBase<any>[] = [
      new GroupField(
        {
          key: 'chanMerParams',
          order: 1,
        },
        [
          new ChanMerSelectField({
            key: 'PID',
            label: 'Alipay Partner ID',
            value: selectedChanMer,
            validators: [Validators.required],
            validatorErrors: {
              required: this.trans('VALIDATION.REQUIRED_SELECT', { name: 'Alipay Partner ID' }),
            },
            options: [],
            compareWith: (o1: any, o2: any) => (o1 && o2 ? o1.id === o2.id : o1 === o2),
            order: 1,
          }),
          new TextboxField({
            key: 'secondaryMerchantID',
            label: 'Alipay secondary merchant id',
            validators: [
              Validators.required,
              Validators.maxLength(AlipaySecondaryMerIDMaxLength),
              Validators.pattern(alphanumericReg),
            ],
            validatorErrors: {
              required: this.trans('VALIDATION.REQUIRED', { name: 'Alipay secondary merchant id' }),
              maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: AlipaySecondaryMerIDMaxLength }),
              pattern: this.trans('VALIDATION.PATTERN.ALPHANUMERIC_ONLY'),
            },
            value: (cmp && cmp.secondaryMerchantID) || '',
            order: 2,
          }),
          new TextboxField({
            key: 'secondaryMerchantName',
            label: 'Alipay secondary merchant name',
            validators: [
              Validators.required,
              Validators.maxLength(AlipaySecondaryMerNameMaxLength),
              Validators.pattern(alphanumericReg),
            ],
            validatorErrors: {
              required: this.trans('VALIDATION.REQUIRED', { name: 'Alipay secondary merchant name' }),
              maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: AlipaySecondaryMerNameMaxLength }),
              pattern: this.trans('VALIDATION.PATTERN.ALPHANUMERIC_ONLY'),
            },
            value: (cmp && cmp.secondaryMerchantName) || '',
            order: 3,
          }),
          new TextboxField({
            key: 'storeID',
            label: 'Alipay store ID',
            validators: [
              Validators.required,
              Validators.maxLength(AlipayStoreIDMaxLength),
              Validators.pattern(alphanumericReg),
            ],
            validatorErrors: {
              required: this.trans('VALIDATION.REQUIRED', { name: 'Alipay store ID' }),
              maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: AlipayStoreIDMaxLength }),
              pattern: this.trans('VALIDATION.PATTERN.ALPHANUMERIC_ONLY'),
            },
            value: (cmp && cmp.storeID) || '',
            order: 5,
          }),
          new TextboxField({
            key: 'storeName',
            label: 'Alipay store name',
            validators: [
              Validators.required,
              Validators.maxLength(AlipayStoreNameMaxLength),
              Validators.pattern(alphanumericReg),
            ],
            validatorErrors: {
              required: this.trans('VALIDATION.REQUIRED', { name: 'Alipay store name' }),
              maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: AlipayStoreNameMaxLength }),
              pattern: this.trans('VALIDATION.PATTERN.ALPHANUMERIC_ONLY'),
            },
            value: (cmp && cmp.storeName) || '',
            order: 6,
          }),
        ],
      ),
      new MCCSelectField({
        key: 'mcc',
        label: 'Alipay merchant industry',
        validators: [Validators.required],
        validatorErrors: {
          required: this.trans('VALIDATION.REQUIRED_SELECT', { name: 'Alipay merchant industry' }),
        },
        value: val && val.mcc ? (val.mcc as IMCC) : undefined,
        mccType: MCCType.Alipay,
        order: 2,
      }),
      new NumberField({
        key: 'fee',
        label: 'Transaction Fee',
        validators: [Validators.required],
        validatorErrors: {
          required: this.trans('VALIDATION.REQUIRED', { name: 'Transaction Fee' }),
        },
        value: (val && val.fee) || undefined,
        order: 3,
      }),
      new SelectField({
        key: 'currency',
        label: 'Channel transaction currency',
        validators: [Validators.required],
        validatorErrors: {
          required: this.trans('VALIDATION.REQUIRED_SELECT', { name: 'Channel transaction currency' }),
        },
        value: (val && val.currency) || undefined,
        options: [],
        order: 4,
      }),
    ]

    return fields
  }

  getWeChatPayChannelFields(val?: IQRRouteOfStore): FieldBase<any>[] {
    let selectedChanMer = null
    let cmp: IStoreChanMerWeChat
    if (val && val.chanMerParams) {
      cmp = val.chanMerParams as IStoreChanMerWeChat
      selectedChanMer = new QrChannel()
      selectedChanMer.id = val.chanMerObjId
      selectedChanMer.chanMerID = cmp.merchantID
    }

    if (val.mccNameEN && (val.mcc as IMCC)) {
      val.mcc = {
        mccEnName: val.mccNameEN,
        mccCode: val.mcc as string,
      }
    }

    const fields: FieldBase<any>[] = [
      new GroupField(
        {
          key: 'chanMerParams',
          order: 1,
        },
        [
          new ChanMerSelectField({
            key: 'merchantID',
            label: 'WeChat Merchant ID',
            value: selectedChanMer,
            validators: [Validators.required],
            validatorErrors: {
              required: this.trans('VALIDATION.REQUIRED_SELECT', { name: 'WeChat Merchant ID' }),
            },
            options: [],
            compareWith: (o1: QrChannel, o2: QrChannel) => (o1 && o2 ? o1.chanMerID === o2.chanMerID : o1 === o2),
          }),
          new TextboxField({
            key: 'subMerchantID',
            label: 'WeChat SubMerchant ID',
            validators: [
              Validators.required,
              Validators.maxLength(WeChatSubMerIDMaxLength),
              Validators.pattern(alphanumericReg),
            ],
            validatorErrors: {
              required: this.trans('VALIDATION.REQUIRED', { name: 'WeChat SubMerchant ID' }),
              maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: WeChatSubMerIDMaxLength }),
              pattern: this.trans('VALIDATION.PATTERN.ALPHANUMERIC_ONLY'),
            },
            value: (cmp && cmp.subMerchantID) || '',
          }),
        ],
      ),
      new MCCSelectField({
        key: 'mcc',
        label: 'WeChat MCC',
        validators: [Validators.required],
        validatorErrors: {
          required: this.trans('VALIDATION.REQUIRED_SELECT', { name: 'WeChat MCC' }),
        },
        value: val && val.mcc ? (val.mcc as IMCC) : undefined,
        mccType: MCCType.WeChat,
        order: 2,
      }),
      new NumberField({
        key: 'fee',
        label: 'Transaction Fee',
        validators: [Validators.required],
        validatorErrors: {
          required: this.trans('VALIDATION.REQUIRED', { name: 'Transaction Fee' }),
        },
        value: (val && val.fee) || undefined,
        order: 3,
      }),
      new SelectField({
        key: 'currency',
        label: 'Channel transaction currency',
        validators: [Validators.required],
        validatorErrors: {
          required: this.trans('VALIDATION.REQUIRED_SELECT', { name: 'Channel transaction currency' }),
        },
        value: (val && val.currency) || undefined,
        options: [],
        order: 4,
      }),
    ]

    return fields
  }

  getTrueMoneyChannelFields(val?: IQRRouteOfStore): FieldBase<any>[] {
    const selectedChanMer: QrChannel = new QrChannel()
    let cmp: IStoreChanMerTRU
    if (val && val.chanMerParams) {
       cmp = val.chanMerParams as IStoreChanMerTRU
       if (cmp.payNearby) {
        this.dataService.setShowShopId(true)
       } else {
        this.dataService.setShowShopId(false)
       }
    }
    if (val) {
      selectedChanMer.id = val.chanMerObjId
    }

    const fields: FieldBase<any>[] = [
      new CheckboxField({
        key: 'payNearby',
        label: this.trans('STORE.TRURMONEY.CHANNEL.FACE'),
        value: ((cmp && cmp.shopID ) || (cmp && cmp.authOnline)) ? cmp.payNearby : true,
        onModelChange: (value, form: FormGroup) => {
          this.dataService.setShowShopId(value)
        },
        required: true,
        order: 1,
      }),
      new CheckboxField({
        key: 'authOnline',
        label: this.trans('STORE.TRURMONEY.CHANNEL.ONLINE'),
        value: (cmp && cmp.authOnline),
        order: 2,
      }),
      new SelectField({
        key: 'currency',
        label: 'Channel transaction currency',
        validators: [Validators.required],
        value: (val && val.currency) || undefined,
        options: [],
        order: 4,
      }),
      new TextboxField({
        key: 'chanMerID',
        label: 'Merchant ID',
        validators: [
          Validators.required,
          Validators.minLength(TruMerIDMinLength),
          Validators.maxLength(TruMerIDMaxLength),
          Validators.pattern(onlyNumberReg),
        ],
        validatorErrors: {
          required: this.trans('VALID.STORE.CHANNEL.REQUIRED.MERCHANTID'),
          minlength: this.trans('VALID.STORE.CHANNEL.MIN'),
          maxlength: this.trans('VALID.STORE.CHANNEL.MAX'),
          pattern: this.trans('VALID.TYPE.STORE.CHANNEL.MERCHANTID'),
        },
        value:  (val && val.chanMerID) || '',
        order: 6,
      }),

      new NumberField({
        key: 'fee',
        label: 'Transaction Fee',
        validators: [Validators.required],
        validatorErrors: {
          required: this.trans('VALID.STORE.CHANNEL.REQUIRED.RATE'),
        },
        value: (val && val.fee) || undefined,
        order: 8,
      }),
      new TextboxField({
        key: 'shopID',
        label: 'shop ID',
        validators: [
          Validators.required,
          Validators.minLength(TruMerIDMinLength),
          Validators.maxLength(TruMerIDMaxLength),
          Validators.pattern(onlyNumberReg),
        ],
        validatorErrors: {
          required: this.trans('VALID.STORE.CHANNEL.REQUIRED.SHOPID'),
          minlength: this.trans('VALID.STORE.CHANNEL.MIN'),
          maxlength: this.trans('VALID.STORE.CHANNEL.MAX'),
          pattern: this.trans('VALID.TYPE.STORE.CHANNEL.SHOPID'),
        },
        value:  (cmp && cmp.shopID) || '',
        order: 9,
      }),
    ]
    return fields
  }


  /*
  getVisaChannelFields(val?: IQRRouteOfStore): FieldBase<any>[] {
    const selectedChanMer: QrChannel = new QrChannel()
    if (val) {
      selectedChanMer.id = val.chanMerObjId,
      selectedChanMer.chanMerID = val.chanMerID
    }

    const fields: FieldBase<any>[] = [
      new ChanMerSelectField({
        key: 'chanMerID',
        label: 'Visa BIN',
        value: selectedChanMer,
        required: true,
        options: [],
        compareWith: (o1: any, o2: any) => (o1 && o2 ? o1.id === o2.id : o1 === o2),
        order: 1,
      }),
      new MCCSelectField({
        key: 'mcc',
        label: 'Visa MCC',
        value: val && val.mcc ? { mccCode: val.mcc, mccEnName: val.mcc } : {},
        mccType: MCCType.Standard,
        order: 4,
      }),
      new NumberField({
        key: 'fee',
        label: 'Transaction Fee',
        value: (val && val.fee) || undefined,
        order: 7,
      }),
    ]

    return fields
  }
  */

  getUPIChannelFields(val?: IQRRouteOfStore): FieldBase<any>[] {
    let selectedChanMer = null
    let cmp: IStoreChanMerUPI
    if (val && val.chanMerParams) {
      cmp = val.chanMerParams as IStoreChanMerUPI
      selectedChanMer = new QrChannel()
      selectedChanMer.id = val.chanMerObjId
      selectedChanMer.chanMerID = cmp.acquiringIIN
      selectedChanMer.chanMerIDSecondary = cmp.forwardingIIN
    }

    if (val.mccNameEN && (val.mcc as IMCC)) {
      val.mcc = {
        mccEnName: val.mccNameEN,
        mccCode: val.mcc as string,
      }
    }

    const fields: FieldBase<any>[] = [
      new GroupField(
        {
          key: 'chanMerParams',
          order: 1,
        },
        [
          new ChanMerSelectField({
            key: 'acquiringIIN',
            label: 'UPI Acquiring IIN',
            value: selectedChanMer,
            validators: [Validators.required],
            validatorErrors: {
              required: this.trans('VALIDATION.REQUIRED_SELECT', { name: 'UPI Acquiring IIN' }),
            },
            options: [],
            compareWith: (o1: any, o2: any) => (o1 && o2 ? o1.id === o2.id : o1 === o2),
            onModelChange: (value: UPIChannel, form: FormGroup) => {
              form.get('forwardingIIN').setValue(value ? value.chanMerIDSecondary : null)
            },
            disabled: !!(val && val.id),
          }),
          new TextboxField({
            key: 'forwardingIIN',
            label: 'UPI Forwarding IIN',
            disabled: true,
            value: (cmp && cmp.forwardingIIN) || '',
          }),
        ],
      ),
      new MCCSelectField({
        key: 'mcc',
        label: 'UPI MCC',
        validators: [Validators.required],
        validatorErrors: {
          required: this.trans('VALIDATION.REQUIRED', { name: 'UPI MCC' }),
        },
        value: val && val.mcc ? (val.mcc as IMCC) : undefined,
        mccType: MCCType.Standard,
        order: 2,
      }),
      new NumberField({
        key: 'fee',
        label: 'Transaction Fee',
        validators: [Validators.required],
        validatorErrors: {
          required: this.trans('VALIDATION.REQUIRED', { name: 'Transaction Fee' }),
        },
        value: (val && val.fee) || undefined,
        order: 3,
      }),
      new SelectField({
        key: 'currency',
        label: 'Channel transaction currency',
        validators: [Validators.required],
        validatorErrors: {
          required: this.trans('VALIDATION.REQUIRED_SELECT', { name: 'Channel transaction currency' }),
        },
        value: (val && val.currency) || undefined,
        options: [],
        order: 4,
      }),
    ]

    return fields
  }
  private trans(str: string, params?: Object): string {
    return this.i18n.fanyi(str, params)
  }
  /*
  getMasterCardChannelFields(val?: IQRRouteOfStore): FieldBase<any>[] {
    const selectedChanMer: QrChannel = new QrChannel()
    if (val) {
      selectedChanMer.id = val.chanMerObjId,
      selectedChanMer.chanMerID = val.chanMerID
    }

    const fields: FieldBase<any>[] = [
      new ChanMerSelectField({
        key: 'chanMerID',
        label: 'MasterCard BIN',
        value: selectedChanMer,
        required: true,
        options: [],
        compareWith: (o1: any, o2: any) => (o1 && o2 ? o1.id === o2.id : o1 === o2),
        order: 1,
      }),
      new TextboxField({
        key: 'chanMerIDSecondary',
        label: 'MasterCard ICA',
        value: (val && val.chanMerIDSecondary) || '',
        order: 2,
      }),
      new MCCSelectField({
        key: 'mcc',
        label: 'MasterCard MCC',
        value: val && val.mcc ? { mccCode: val.mcc, mccEnName: val.mcc } : {},
        mccType: MCCType.Standard,
        order: 4,
      }),
      new NumberField({
        key: 'fee',
        label: 'Transaction Fee',
        value: (val && val.fee) || undefined,
        order: 7,
      }),
    ]

    return fields
  }
  */

  /*
  getFPSChannelFields(val?: IQRRouteOfStore): FieldBase<any>[] {
    const selectedChanMer: QrChannel = new QrChannel()
    if (val) {
      selectedChanMer.id = val.chanMerObjId,
      selectedChanMer.chanMerID = val.chanMerID
    }

    const fields: FieldBase<any>[] = [
      new ChanMerSelectField({
        key: 'chanMerID',
        label: 'FPS Bank ID',
        value: selectedChanMer,
        required: true,
        options: [],
        compareWith: (o1: any, o2: any) => (o1 && o2 ? o1.id === o2.id : o1 === o2),
        order: 1,
      }),
      new TextboxField({
        key: 'chanMerIDSecondary',
        label: 'FPS GUID',
        value: (val && val.chanMerIDSecondary) || '',
        order: 2,
      }),
      new TextboxField({
        key: 'chanMerIDTertiary',
        label: 'FPS Identifier',
        value: (val && val.chanMerIDTertiary) || '',
        order: 3,
      }),
      new MCCSelectField({
        key: 'mcc',
        label: 'FPS MCC',
        value: val && val.mcc ? { mccCode: val.mcc, mccEnName: val.mcc } : {},
        mccType: MCCType.Standard,
        order: 4,
      }),
      new NumberField({
        key: 'fee',
        label: 'Transaction Fee',
        value: (val && val.fee) || undefined,
        order: 7,
      }),
    ]

    return fields
  }
  */
}
